﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using ProtocolBuilder.Model.Field;

namespace ProtocolBuilder
{
    class Packet
    {
        private XElement xmlElement;

        public XElement XElement
        {
            get
            {
                return this.xmlElement;
            }
        }

        public int ID
        {
            get
            {
                return int.Parse(this.xmlElement.Attribute("id").Value);
            }
            set
            {
                this.xmlElement.Attribute("id").Value = value.ToString();
            }
        }

        public string PacketName
        {
            get
            {
                return this.xmlElement.Attribute("name").Value;
            }
            set
            {
                this.xmlElement.Attribute("name").Value = value;
            }
        }

        public string Description
        {
            get
            {
                return this.xmlElement.Attribute("description").Value;
            }
            set
            {
                this.xmlElement.Attribute("description").Value = value;
            }
        }

        public PacketType PacketType
        {
            get
            {
                return (PacketType)Enum.Parse(typeof(PacketType), this.xmlElement.Attribute("type").Value);
            }
            set
            {
                this.xmlElement.Attribute("type").Value = value.ToString();
            }
        }

        public IList<AbsField> GenerateFieldList()
        {
            List<AbsField> result = new List<AbsField>();
            foreach (XElement child in this.xmlElement.Elements("field"))
            {
                result.Add(FieldFactory.CreateField(child));
            }
            return result;
        }

        public Packet()
            : this(true)
        { }

        private Packet(bool initialize)
        {
            if (initialize)
            {
                this.Initialize();
            }
        }

        public void RemoveAllFields()
        {
            this.xmlElement.RemoveNodes();
        }

        public void AddField(AbsField field)
        {
            this.xmlElement.Add(field.XmlElement);
        }

        private void Initialize()
        {
            this.xmlElement = new XElement("packet", new XAttribute("id", 0),
                new XAttribute("name", string.Empty),
                new XAttribute("description", string.Empty),
                new XAttribute("type", string.Empty));
            this.PacketType = PacketType.Request;
        }

        public static Packet FromXml(XElement element)
        {
            if (element == null || element.Name.Equals("packet"))
            {
                throw new ArgumentException("not a packet element.");
            }

            Packet result = new Packet(false);
            result.xmlElement = element;

            return result;
        }
    }
}
